package com.hyxt.provider;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.hyxt.DTO.T809ClientHandler;
import com.hyxt.api.T809ClientService;
import com.hyxt.dao.RedisServiceDAO;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.HashMap;
import java.util.Map;

import static com.hyxt.DTO.T809ClientHandler.channelMap;

/**
 * @author shenp
 * @version v1.0
 * @Description
 * @Date: Create in 10:18 2017/11/23
 * @Modifide By:
 **/
@Service(interfaceClass = T809ClientService.class,version = "1.0.0")
public class T809ClientServiceImpl implements T809ClientService {
    /**
     * 日志
     */
    private Log log = LogFactory.getLog(T809ClientServiceImpl.class);
    /**
     * redis对象
     */
    @Reference(version = "1.0.0")
    RedisServiceDAO redisServiceDAO;
    @Override
    public boolean startClient(String ip, Integer port, Integer mainOrBranch, Integer sign,Integer accessOrForward) {
        EventLoopGroup group = new NioEventLoopGroup();
        try{
            Bootstrap b =  new Bootstrap();
            b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() {

                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast("decoder", new ByteArrayDecoder());
                    ch.pipeline().addLast("encoder", new ByteArrayEncoder());
                    ch.pipeline().addLast("handler",new T809ClientHandler(mainOrBranch,sign,redisServiceDAO,accessOrForward));
                }
            });
            //连接客户端
            ChannelFuture f = b.connect(ip, port).sync();
            log.info("客户端启动成功");
            return true;
        }catch (Exception e){
            log.info("客户端启动失败");
            return false;
        }
    }

    @Override
    public boolean deleteChannel(Integer sign, Integer mainOrBranch) {
//        Channel channel  = findChannle(sign,mainOrBranch);
        //获取ip+端口
        String ipAndPort = findIpAndPort(sign,mainOrBranch);
        //获取链路
        Channel channel = channelMap.get(ipAndPort);
        //删除redis中的对应关系
        redisServiceDAO.delete(sign+mainOrBranch+"",0);
        //删除缓存中的链路
        channelMap.remove(ipAndPort);
        if (!(channel==null)){
            channel.close();
        }
        return true;
    }

    public Channel findChannle(Integer sign, Integer mainOrBranch) {

        String ipAndPort = findIpAndPort(sign,mainOrBranch);
        if (channelMap.containsKey(ipAndPort)){
            //查找链路
            return channelMap.get(ipAndPort);
        }
        return null;
    }

    @Override
    public boolean sendMessage(Integer sign, Integer mainOrBranch, byte[] bytes) {

        //查找链路
        Channel channel = findChannle(sign,mainOrBranch);
        if (!(channel==null)){
            //发送数据
            channel.writeAndFlush(bytes);
            return true;
        }
        return false;
    }
    /**
     * 从redis中查找对应标识的ip+port
     * @return
     */
    public String findIpAndPort(Integer sign, Integer mainOrBranch){
        Map<String,String> map = new HashMap<String,String>();
        //从redis中获取对应关系
        map = redisServiceDAO.getMap(sign+mainOrBranch+"",0);
        //获取ip+端口
        return map.get("ip");
    }
}
